<template>
  <t-modal
    title="项目流程"
    width="1264px"
    :visible="visible"
    @cancel="closeModal()"
    wrapClassName="add-modal-container"
    forceRender
    v-bind="footer"
  >
    <div class="curve-modal-body">
      <div class="title">{{ parameter.proName }}</div>
      <div class="date">
        <div class="item">开始时间：{{ dataSource.startTime || "-" }}</div>
        <div class="item">结束时间：{{ dataSource.endTime || "-" }}</div>
        <div class="item">
          状态：
          <span class="state">
            <icon-fonts
              icon="icon-daojishi"
              type="small"
              style="margin-right:5px;"
            >
            </icon-fonts>
            {{ filterStatus(dataSource.status) || "-" }}
          </span>
        </div>
      </div>
      <div id="graph-container"></div>
      <div class="legend">
        <div class="legend-item">未开始</div>
        <div class="legend-item">进行中</div>
        <div class="legend-item">已完成</div>
        <div class="legend-item">延期</div>
      </div>
    </div>
  </t-modal>
</template>

<script>
import { Graph, Shape } from "@antv/x6";
import "@antv/x6-vue-shape";
import { detailFlowPath, getListByProcessId } from "@/api/knowledgeBase";
export default {
  components: {},
  props: {
    visible: {
      type: Boolean,
      default: false,
    },
    parameter: {
      type: Object,
      default: () => {
        return {};
      },
    },
    footer: {
      type: Object,
      default: () => {
        return { footer: null };
      },
    },
  },
  data() {
    return {
      graph: null,
      cells: [],
      status: [],
      dataSource: {},
    };
  },
  computed: {},
  watch: {
    visible: {
      handler(val) {
        if (val) {
          this.$nextTick(() => {
            // 初始化画布
            this.initGraph();
            // 初始化连接桩
            this.initPorts();
            // 渲染所有左侧控件图形
            this.loadStencil();
            // 初始化数据接口
            this.getData();
          });
        }
      },
      immediate: true,
    },
  },
  methods: {
    filterStatus(val) {
      switch (Number(val)) {
        case 0:
          return "未开始";
        case 1:
          return "进行中";
        case 2:
          return "已完成";
        default:
          break;
      }
    },

    getData() {
      Promise.all([this.getCellsData(), this.getStateData()])
        .then(() => {
          let { status } = this;
          // 获取所有节点
          let nodes = this.graph.getNodes();
          // 获取所有边
          let edges = this.graph.getEdges();

          //节点颜色调整
          nodes.forEach((item) => {
            status.forEach((v) => {
              if (item.id == v.nodeId) {
                switch (v.nodeStatus) {
                  //未开始
                  case "0":
                    item.setAttrs({
                      body: {
                        stroke: "#D9D9D9",
                        fill: "rgba(255, 255, 255, 0.1)",
                      },
                      text: {
                        fill: "#8C8C8C",
                      },
                    });
                    break;
                  //进行中
                  case "1":
                    item.setAttrs({
                      body: {
                        stroke: "#239b53",
                        fill: "rgba(35, 155, 83, 0.10)",
                      },
                      text: {
                        fill: "#239b53",
                      },
                    });
                    break;
                  //已完成
                  case "2":
                    item.setAttrs({
                      body: {
                        stroke: "#1890FF",
                        fill: "rgba(24, 144, 255, 0.10)",
                      },
                      text: {
                        fill: "#1890FF",
                      },
                    });
                    break;
                  //延期
                  case "3":
                    item.setAttrs({
                      body: {
                        stroke: "#FF3F4A",
                        fill: "rgba(255, 63, 74, 0.10)",
                      },
                      text: {
                        fill: "#FF3F4A",
                      },
                    });
                    break;

                  default:
                    break;
                }
              }
            });
          });
          //边颜色调整
          edges.forEach((item) => {
            status.forEach((v) => {
              if (item.source.cell == v.nodeId) {
                switch (v.nodeStatus) {
                  //未开始
                  case "0":
                    item.setAttrs({
                      line: {
                        stroke: "#8A9295",
                      },
                    });
                    break;
                  //进行中
                  case "1":
                    item.setAttrs({
                      line: {
                        stroke: "#239b53",
                      },
                    });
                    break;
                  //已完成
                  case "2":
                    item.setAttrs({
                      line: {
                        stroke: "#1890FF",
                      },
                    });
                    break;
                  //延期
                  case "3":
                    item.setAttrs({
                      line: {
                        stroke: "#FF3F4A",
                      },
                    });
                    break;

                  default:
                    break;
                }
              }
            });
          });
        })
        .catch((_) => {});
    },

    // 初始化画布
    initGraph() {
      // 初始化画布
      this.graph = new Graph({
        container: document.getElementById("graph-container"),
        //禁止节点平移
        interacting: function(cellView) {
          //   if (
          //     cellView.cell.getData() != undefined &&
          //     !cellView.cell.getData().disableMove
          //   ) {
          //     return { nodeMovable: false };
          //   }
          return { nodeMovable: false };
        },
        grid: {
          // 绘制网格
          visible: true,
          // 指定网格类型
          type: "mesh",
          args: {
            color: "#ddd", // 网格线/点颜色
            thickness: 1, // 网格线宽度/网点大小
          },
        },
        async: true,
        //允许画布拖拽
        panning: {
          enabled: true,
          eventTypes: ["leftMouseDown", "mouseWheel"],
        },
        mousewheel: {
          enabled: true,
          zoomAtMousePosition: true,
          modifiers: "ctrl",
          minScale: 0.5,
          maxScale: 3,
        },
        connecting: {
          router: {
            name: "manhattan",
            args: {
              padding: 1,
            },
          },
          connector: {
            name: "rounded",
            args: {
              radius: 8,
            },
          },
          anchor: "center",
          connectionPoint: "anchor",
          allowBlank: false,
          snap: {
            radius: 20,
          },
          createEdge() {
            return new Shape.Edge({
              attrs: {
                line: {
                  stroke: "#A2B1C3",
                  strokeWidth: 2,
                  targetMarker: {
                    name: "block",
                    width: 12,
                    height: 8,
                  },
                },
              },
              zIndex: 0,
            });
          },
          validateConnection({ targetMagnet }) {
            return !!targetMagnet;
          },
        },
        highlighting: {
          magnetAdsorbed: {
            name: "stroke",
            args: {
              attrs: {
                fill: "#5F95FF",
                stroke: "#5F95FF",
              },
            },
          },
        },
      });
    },

    // 初始化链接桩
    initPorts() {
      this.ports = {
        groups: {
          top: {
            position: "top",
            attrs: {
              circle: {
                r: 4,
                magnet: true,
                stroke: "#5F95FF",
                strokeWidth: 1,
                fill: "#fff",
                style: {
                  visibility: "hidden",
                },
              },
            },
          },
          right: {
            position: "right",
            attrs: {
              circle: {
                r: 4,
                magnet: true,
                stroke: "#5F95FF",
                strokeWidth: 1,
                fill: "#fff",
                style: {
                  visibility: "hidden",
                },
              },
            },
          },
          bottom: {
            position: "bottom",
            attrs: {
              circle: {
                r: 4,
                magnet: true,
                stroke: "#5F95FF",
                strokeWidth: 1,
                fill: "#fff",
                style: {
                  visibility: "hidden",
                },
              },
            },
          },
          left: {
            position: "left",
            attrs: {
              circle: {
                r: 4,
                magnet: true,
                stroke: "#5F95FF",
                strokeWidth: 1,
                fill: "#fff",
                style: {
                  visibility: "hidden",
                },
              },
            },
          },
        },
        items: [
          {
            group: "top",
          },
          {
            group: "right",
          },
          {
            group: "bottom",
          },
          {
            group: "left",
          },
        ],
      };
    },

    // 渲染所有左侧控件图形
    loadStencil() {
      Graph.registerNode(
        "custom-rect",
        {
          inherit: "rect",
          width: 100,
          height: 40,
          attrs: {
            body: {
              strokeWidth: 1,
              stroke: "#d9d9d9",
              fill: "#fff",
            },
            text: {
              fontSize: 12,
              fill: "#8c8c8c",
            },
          },
          ports: { ...this.ports },
        },
        true
      );

      Graph.registerNode(
        "custom-circle",
        {
          inherit: "circle",
          width: 48,
          height: 48,
          attrs: {
            body: {
              strokeWidth: 1,
              stroke: "#d9d9d9",
              fill: "#fff",
            },
            text: {
              fontSize: 12,
              fill: "#8c8c8c",
            },
          },
          ports: { ...this.ports },
        },
        true
      );
    },

    getCellsData() {
      let { proCode } = this.parameter;
      return new Promise((resolve, reject) => {
        detailFlowPath({ proCode })
          .then((res) => {
            let source = JSON.parse(res.data?.processContent ?? "[]") ?? [];
            source.forEach((v) => {
              v.tools = [];
            });
            this.cells = source;
            this.$nextTick(() => {
              // 清空画布
              this.graph.clearCells();
              // 渲染节点数据
              this.graph.fromJSON({
                cells: this.cells,
              });
            });
            resolve();
          })
          .catch((_) => {
            this.cells = [];
            reject();
          })
          .finally((_) => {});
      });
    },
    //查询节点状态
    getStateData() {
      let { uuid } = this.parameter;
      return new Promise((resolve, reject) => {
        getListByProcessId({ processId: uuid })
          .then((res) => {
            let { data } = res;
            this.dataSource = data;
            this.status = data?.nodeList;
            resolve();
          })
          .catch((_) => {
            this.status = [];
            reject();
          });
      });
    },

    //关闭
    closeModal() {
      this.graph && this.graph.dispose();
      this.$emit("update:visible", false);
    },
  },
};
</script>

<style lang="less" scoped>
/deep/.add-modal-container {
  .ant-modal-body {
    padding: 0 !important;
    .curve-modal-body {
      height: 700px;
      display: flex;
      flex-direction: column;
      padding: 32px 24px;
      box-sizing: border-box;
      position: relative;
      .title {
        text-align: center;
        font-weight: 400;
        font-size: 32px;
        color: #333333;
      }
      .date {
        display: flex;
        justify-content: center;
        margin: 16px 0 26px 0;
        .item {
          margin-right: 50px;
          font-weight: 400;
          font-size: 14px;
          color: #8a9295;
          .state {
            color: #ff6f42;
          }
        }
      }
      #graph-container {
        flex: 1;
      }
      .legend {
        position: absolute;
        left: 50%;
        transform: translate(-50%);
        bottom: 48px;
        display: flex;
        align-items: center;
        .legend-item {
          font-weight: 400;
          font-size: 14px;
          color: #666666;
          margin-right: 48px;
          &::before {
            display: inline-block;
            content: "";
            position: relative;
            top: 1px;
            margin-right: 10px;
            width: 20px;
            height: 12px;
          }
        }
        .legend-item:nth-child(1) {
          &::before {
            background: #8a9295;
          }
        }
        .legend-item:nth-child(2) {
          &::before {
            background: #239b53;
          }
        }
        .legend-item:nth-child(3) {
          &::before {
            background: #1890ff;
          }
        }
        .legend-item:nth-child(4) {
          &::before {
            background: #ff3f4a;
          }
        }
      }
    }
  }
}
</style>
